package dk.itu.samd.group2.tagapastry.messages;

import dk.itu.samd.group2.tagapastry.Index;
import dk.itu.samd.group2.tagapastry.NodeState;
import dk.itu.samd.group2.tagapastry.Tag;
import dk.itu.samd.group2.tagapastry.TagFactory;
import dk.itu.samd.group2.tagapastry.TagapastryImpl;
import rice.environment.logging.Logger;
import rice.p2p.commonapi.Id;
import rice.p2p.commonapi.NodeHandle;
import rice.pastry.PastryNode;
import rice.pastry.leafset.LeafSet;

public class ReplicationMaintenanceMsg extends TagapastryMsg {
	
	public static final int TYPE = 12;
	private static final long serialVersionUID = TYPE;
	
	/*
	 * Its just to initiate the flow. This message will
	 * take advantage of ReplicationMsg anyway.
	 */
	public ReplicationMaintenanceMsg(NodeHandle sender)
	{
		super(null,sender,sender);
	}

	@Override
	public Id getRecepientId() {
		return originalSender.getId();
	}

	@Override
	public short getType() {
		return TYPE;
	}
	
	public String toString() {
		return super.toString() + " }";
	}

	@Override
	public void execute(TagapastryImpl impl) {

		// Iterate over leaf set and send information if there is actually
		// a change to underlying indexes
		PastryNode pn = (PastryNode)impl.getNode();
		LeafSet leafSet = pn.getLeafSet();
//		if(impl.getLoger().level <= Logger.FINER)
			//impl.getLoger().log("Starting iterating through leaf set for node " + pn);
		
		for (int i=-leafSet.ccwSize(); i<=leafSet.cwSize(); i++) {
			if (i != 0) { // don't send to self
				// select the item
				NodeHandle nh = leafSet.get(i);
       
				// Update only if at least one index changed
//				boolean update = false; // optimistic
//				for(Index idx : impl.getIndexes().values()) {
//					if(idx.isDeltaChanged()) { // Not sure though if that's enough
//						update = true;
//						break;
//					}
//				}
//				
//				// If nothing to update then skip
//				if(!update) continue;
				
				if(impl.getIndexes() == null || impl.getIndexes().size() == 0)
					continue;
				
				//System.out.println("Synchronize to node: " + nh + " from node: " + impl.getNodeHandle());
				// send the message directly to the node
				
				Tag tag = TagFactory.generateTag("", "");
				NodeState nodeState = new NodeState(impl.getIndexes(),impl.getRetractionThreshold(),impl.getExpansionThreshold());
				ReplicationMsg rmsg = new ReplicationMsg(tag, impl.getNodeHandle(), nh, nodeState);
          
				// wait a bit - like in tutorial
				//try {
					//impl.getEnvironment().getTimeSource().sleep(1);
					// Send message!
					impl.send(rmsg);
				//} catch (InterruptedException e) {
					// Ideally log error
					//e.printStackTrace();
					//continue;
				//}
			}
		}
	}

}
